#include <gtest/gtest.h>
#include <gflags/gflags.h>

#include "channel.hpp"
#include "etcd.hpp"     //服务注册
#include <thread>
#include <vector>
#include "utils.hpp"

#include "message.pb.h"
#include "friend.pb.h"
#include "base.pb.h"
#include "user.pb.h"
#include <boost/date_time/posix_time/posix_time.hpp>
DEFINE_bool(run_mode, false, "程序的运行模式, fasle-调试; true-发布;");
DEFINE_string(log_file, "", "发布模式下, 用于指定日志的输出文件");
DEFINE_int32(log_level, 0, "发布模式下, 用于指定日志输出等级");  //trace default 0

DEFINE_string(etcd_host, "http://127.0.0.1:2379", "这是服务中心地址");
DEFINE_string(base_service, "/service", "服务监控根目录");
DEFINE_string(friend_service, "/service/friend_service", "服务监控目录");

xchat::ServiceManager::ptr _user_channels;
auto service_manager = std::make_shared<xchat::ServiceManager>();


void apply_test(const std::string &uid, const std::string &pid)
{
    auto channel = service_manager->choose(FLAGS_friend_service);
    ASSERT_TRUE(channel != nullptr);
    xchat::FriendService_Stub stub(channel.get());
    xchat::FriendAddReq req;
    
    req.set_request_id(xchat::uuid());
    req.set_user_id(uid);
    req.set_respondent_id(pid);
    //req.set_session_id("这一栏没用");


    std::unique_ptr<xchat::FriendAddRsp> rsp(new xchat::FriendAddRsp());
    std::unique_ptr<brpc::Controller> cntl(new brpc::Controller());
    stub.FriendAdd(cntl.get(), &req, rsp.get(), nullptr); // 同步调用
    ASSERT_FALSE(cntl->Failed());
    ASSERT_TRUE(rsp->success());
}
void get_apply_list_test(const std::string &uid)
{
    auto channel = service_manager->choose(FLAGS_friend_service);
    ASSERT_TRUE(channel != nullptr);
    xchat::FriendService_Stub stub(channel.get());
    xchat::GetPendingFriendEventListReq req;
    
    req.set_request_id(xchat::uuid());
    req.set_user_id(uid);


    std::unique_ptr<xchat::GetPendingFriendEventListRsp> rsp(new xchat::GetPendingFriendEventListRsp());
    std::unique_ptr<brpc::Controller> cntl(new brpc::Controller());
    stub.GetPendingFriendEventList(cntl.get(), &req, rsp.get(), nullptr); // 同步调用
    ASSERT_FALSE(cntl->Failed());
    ASSERT_TRUE(rsp->success());

    for(auto &i : rsp->event())
    {
        std::cout << "-----------------" << std::endl;
        std::cout << "id:           " << i.sender().user_id() << std::endl;
        std::cout << "nickname:     " << i.sender().nickname() << std::endl;
        std::cout << "description:  " << i.sender().description() << std::endl;
        std::cout << "phone:        " << i.sender().phone() << std::endl;
        std::cout << "avatar:       " << i.sender().avatar() << std::endl;
    }
}
void process_apply_test(const std::string &pid, const std::string &uid, bool agree)
{
    auto channel = service_manager->choose(FLAGS_friend_service);
    ASSERT_TRUE(channel != nullptr);
    xchat::FriendService_Stub stub(channel.get());
    xchat::FriendAddProcessReq req;
    
    req.set_request_id(xchat::uuid());
    req.set_apply_user_id(uid);
    req.set_user_id(pid);
    req.set_agree(agree);

    std::unique_ptr<xchat::FriendAddProcessRsp> rsp(new xchat::FriendAddProcessRsp());
    std::unique_ptr<brpc::Controller> cntl(new brpc::Controller());
    stub.FriendAddProcess(cntl.get(), &req, rsp.get(), nullptr); // 同步调用
    ASSERT_FALSE(cntl->Failed());
    ASSERT_TRUE(rsp->success());

    if(agree)
    {
        std::cout << rsp->new_session_id() << std::endl;
    }
}
void search_test(const std::string &uid, const std::string &search_key)
{
    auto channel = service_manager->choose(FLAGS_friend_service);
    ASSERT_TRUE(channel != nullptr);
    xchat::FriendService_Stub stub(channel.get());
    xchat::FriendSearchReq req;
    
    req.set_request_id(xchat::uuid());
    req.set_search_key(search_key);
    req.set_user_id(uid);

    std::unique_ptr<xchat::FriendSearchRsp> rsp(new xchat::FriendSearchRsp());
    std::unique_ptr<brpc::Controller> cntl(new brpc::Controller());
    stub.FriendSearch(cntl.get(), &req, rsp.get(), nullptr); // 同步调用
    ASSERT_FALSE(cntl->Failed());
    ASSERT_TRUE(rsp->success());

    for(auto &i : rsp->user_info())
    {
        std::cout << "-----------------" << std::endl;
        std::cout << "id:           " << i.user_id() << std::endl;
        std::cout << "nickname:     " << i.nickname() << std::endl;
        std::cout << "description:  " << i.description() << std::endl;
        std::cout << "phone:        " << i.phone() << std::endl;
        std::cout << "avatar:       " << i.avatar() << std::endl;
    }
}
void friend_list_test(const std::string &uid)
{
    std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
    auto channel = service_manager->choose(FLAGS_friend_service);
    ASSERT_TRUE(channel != nullptr);
    xchat::FriendService_Stub stub(channel.get());
    xchat::GetFriendListReq req;
    
    req.set_request_id(xchat::uuid());
    req.set_user_id(uid);

    std::unique_ptr<xchat::GetFriendListRsp> rsp(new xchat::GetFriendListRsp());
    std::unique_ptr<brpc::Controller> cntl(new brpc::Controller());
    stub.GetFriendList(cntl.get(), &req, rsp.get(), nullptr); // 同步调用
    ASSERT_FALSE(cntl->Failed());
    ASSERT_TRUE(rsp->success());

    for(auto &i : rsp->friend_list())
    {
        std::cout << "-----------------" << std::endl;
        std::cout << "id:           " << i.user_id() << std::endl;
        std::cout << "nickname:     " << i.nickname() << std::endl;
        std::cout << "description:  " << i.description() << std::endl;
        std::cout << "phone:        " << i.phone() << std::endl;
        std::cout << "avatar:       " << i.avatar() << std::endl;
    }
}
void friend_remove_test(const std::string &uid, const std::string& friend_id)
{
    std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
    auto channel = service_manager->choose(FLAGS_friend_service);
    ASSERT_TRUE(channel != nullptr);
    xchat::FriendService_Stub stub(channel.get());
    xchat::FriendRemoveReq req;
    
    req.set_request_id(xchat::uuid());
    req.set_user_id(uid);
    req.set_peer_id(friend_id);

    std::unique_ptr<xchat::FriendRemoveRsp> rsp(new xchat::FriendRemoveRsp());
    std::unique_ptr<brpc::Controller> cntl(new brpc::Controller());
    stub.FriendRemove(cntl.get(), &req, rsp.get(), nullptr); // 同步调用
    ASSERT_FALSE(cntl->Failed());
    ASSERT_TRUE(rsp->success());
}
void create_groupcss_test(const std::string &uid, const std::vector<std::string> id_lists)
{
    std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
    auto channel = service_manager->choose(FLAGS_friend_service);
    ASSERT_TRUE(channel != nullptr);
    xchat::FriendService_Stub stub(channel.get());
    xchat::ChatSessionCreateReq req;
    
    req.set_request_id(xchat::uuid());
    req.set_user_id(uid);
    req.set_chat_session_name("相亲相爱一家人");
    for(auto &i : id_lists)
    {
        req.add_member_id_list(i);
    }

    std::unique_ptr<xchat::ChatSessionCreateRsp> rsp(new xchat::ChatSessionCreateRsp());
    std::unique_ptr<brpc::Controller> cntl(new brpc::Controller());
    stub.ChatSessionCreate(cntl.get(), &req, rsp.get(), nullptr); // 同步调用
    ASSERT_FALSE(cntl->Failed());
    ASSERT_TRUE(rsp->success());

    std::cout << "session_id: " << rsp->chat_session_info().chat_session_id() << std::endl;
    std::cout << "session_name: " << rsp->chat_session_info().chat_session_name() << std::endl;
}
void css_member_test(const std::string &uid, const std::string &cssid)
{
    std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
    auto channel = service_manager->choose(FLAGS_friend_service);
    ASSERT_TRUE(channel != nullptr);
    xchat::FriendService_Stub stub(channel.get());
    xchat::GetChatSessionMemberReq req;
    
    req.set_request_id(xchat::uuid());
    req.set_user_id(uid);
    req.set_chat_session_id(cssid);

    std::unique_ptr<xchat::GetChatSessionMemberRsp> rsp(new xchat::GetChatSessionMemberRsp());
    std::unique_ptr<brpc::Controller> cntl(new brpc::Controller());
    stub.GetChatSessionMember(cntl.get(), &req, rsp.get(), nullptr); // 同步调用
    ASSERT_FALSE(cntl->Failed());
    ASSERT_TRUE(rsp->success());

    for(auto &i : rsp->member_info_list())
    {
        std::cout << "-----------------" << std::endl;
        std::cout << "id:           " << i.user_id() << std::endl;
        std::cout << "nickname:     " << i.nickname() << std::endl;
        std::cout << "description:  " << i.description() << std::endl;
        std::cout << "phone:        " << i.phone() << std::endl;
        std::cout << "avatar:       " << i.avatar() << std::endl;
    }
}
void css_list_test(const std::string &uid)
{
    std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
    auto channel = service_manager->choose(FLAGS_friend_service);
    ASSERT_TRUE(channel != nullptr);
    xchat::FriendService_Stub stub(channel.get());
    xchat::GetChatSessionListReq req;
    
    req.set_request_id(xchat::uuid());
    req.set_user_id(uid);

    std::unique_ptr<xchat::GetChatSessionListRsp> rsp(new xchat::GetChatSessionListRsp());
    std::unique_ptr<brpc::Controller> cntl(new brpc::Controller());
    stub.GetChatSessionList(cntl.get(), &req, rsp.get(), nullptr); // 同步调用
    ASSERT_FALSE(cntl->Failed());
    ASSERT_TRUE(rsp->success());

    for(auto &i : rsp->chat_session_info_list())
    {
        if(i.single_chat_friend_id() == "") continue;
        std::cout << "-----------------" << std::endl;
        std::cout << "id:                  " << i.single_chat_friend_id() << std::endl;
        std::cout << "chat_session_id:     " << i.chat_session_id() << std::endl;
        std::cout << "chat_session_name:   " << i.chat_session_name() << std::endl;
        std::cout << "chat_avatar:         " << i.avatar() << std::endl;

        std::cout << "msg_id:              " << i.prev_message().message_id() << std::endl;
        std::cout << "msg_chat_session_id: " << i.prev_message().chat_session_id() << std::endl;
        std::cout << "msg_timestamp:       " << boost::posix_time::to_simple_string(boost::posix_time::from_time_t(i.prev_message().timestamp())) << std::endl;
        std::cout << "user_id:             " << i.prev_message().sender().user_id() << std::endl;
        std::cout << "nickname:            " << i.prev_message().sender().nickname() << std::endl;
        std::cout << "avatar:              " << i.prev_message().sender().avatar() << std::endl;
        if(i.prev_message().message().message_type() == xchat::MessageType::STRING)
        {
            std::cout << "文本消息: " << i.prev_message().message().string_message().content() << std::endl;
        }
        else if(i.prev_message().message().message_type() == xchat::MessageType::IMAGE)
        {
            std::cout << "图片消息ID: " << i.prev_message().message().image_message().file_id() << std::endl;
            std::cout << "图片消息内容: " << i.prev_message().message().image_message().image_content() << std::endl;
        }
        else if(i.prev_message().message().message_type() == xchat::MessageType::FILE)
        {
            std::cout << "文件消息ID: " << i.prev_message().message().file_message().file_id() << std::endl;
            std::cout << "文件消息文件名: " << i.prev_message().message().file_message().file_name() << std::endl;
            std::cout << "文件消息文件大小: " << i.prev_message().message().file_message().file_size() << std::endl;
            std::cout << "文件消息内容: " << i.prev_message().message().file_message().file_contents() << std::endl;
        }
        else if(i.prev_message().message().message_type() == xchat::MessageType::SPEECH)
        {
            std::cout << "语音消息ID: " << i.prev_message().message().speech_message().file_id() << std::endl;
            std::cout << "语音消息文件名: " << i.prev_message().message().speech_message().file_contents() << std::endl;
        }
        else
        {
            std::cout << "未知消息类型" << std::endl;
            abort();
        }

    }
    std::cout << "群聊信息" << std::endl;
    for(auto &i : rsp->chat_session_info_list())
    {
        if(i.single_chat_friend_id() != "") continue;
        std::cout << "-----------------" << std::endl;
        std::cout << "chat_session_id:     " << i.chat_session_id() << std::endl;
        std::cout << "chat_session_name:   " << i.chat_session_name() << std::endl;

        std::cout << "msg_id:              " << i.prev_message().message_id() << std::endl;
        std::cout << "msg_chat_session_id: " << i.prev_message().chat_session_id() << std::endl;
        std::cout << "msg_timestamp:       " << boost::posix_time::to_simple_string(boost::posix_time::from_time_t(i.prev_message().timestamp())) << std::endl;
        std::cout << "user_id:             " << i.prev_message().sender().user_id() << std::endl;
        std::cout << "nickname:            " << i.prev_message().sender().nickname() << std::endl;
        std::cout << "avatar:              " << i.prev_message().sender().avatar() << std::endl;
        if(i.prev_message().message().message_type() == xchat::MessageType::STRING)
        {
            std::cout << "文本消息: " << i.prev_message().message().string_message().content() << std::endl;
        }
        else if(i.prev_message().message().message_type() == xchat::MessageType::IMAGE)
        {
            std::cout << "图片消息ID: " << i.prev_message().message().image_message().file_id() << std::endl;
            std::cout << "图片消息内容: " << i.prev_message().message().image_message().image_content() << std::endl;
        }
        else if(i.prev_message().message().message_type() == xchat::MessageType::FILE)
        {
            std::cout << "文件消息ID: " << i.prev_message().message().file_message().file_id() << std::endl;
            std::cout << "文件消息文件名: " << i.prev_message().message().file_message().file_name() << std::endl;
            std::cout << "文件消息文件大小: " << i.prev_message().message().file_message().file_size() << std::endl;
            std::cout << "文件消息内容: " << i.prev_message().message().file_message().file_contents() << std::endl;
        }
        else if(i.prev_message().message().message_type() == xchat::MessageType::SPEECH)
        {
            std::cout << "语音消息ID: " << i.prev_message().message().speech_message().file_id() << std::endl;
            std::cout << "语音消息文件名: " << i.prev_message().message().speech_message().file_contents() << std::endl;
        }
        else
        {
            std::cout << "未知消息类型" << std::endl;
            abort();
        }
    }
}
int main(int argc, char* argv[])
{
    google::ParseCommandLineFlags(&argc, &argv, true);
    
    xchat::init_logger(FLAGS_run_mode, FLAGS_log_file, FLAGS_log_level);


    //1.先构造Rpc信道管理对象
    service_manager->declared(FLAGS_friend_service);
    auto put_cb = std::bind(&xchat::ServiceManager::onServiceOnline, service_manager.get(), std::placeholders::_1, std::placeholders::_2);
    auto del_cb = std::bind(&xchat::ServiceManager::onServiceOffline, service_manager.get(), std::placeholders::_1, std::placeholders::_2);
    //2.构造服务发现对象
    xchat::Discovery::ptr dclient = std::make_shared<xchat::Discovery>(FLAGS_etcd_host, FLAGS_base_service, put_cb, del_cb);
    //21df-12664a1c-0000 张三三三 f7aa-b126b9c7-0001张三
    //41d1-b0335c8f-0000 李四 1460-080c2225-0001 王五 9dbd-b84377c2-0002赵六
    //b4ce-6ceee502-0003 王五五

    //张三三三向张三申请好友
    //apply_test("21df-12664a1c-0000", "f7aa-b126b9c7-0001");
    //李四向张三申请好友
    //apply_test("41d1-b0335c8f-0000", "f7aa-b126b9c7-0001");
    //王五向张三申请好友
    //apply_test("1460-080c2225-0001", "f7aa-b126b9c7-0001");

    //get_apply_list_test("f7aa-b126b9c7-0001");

    // process_apply_test("f7aa-b126b9c7-0001", "21df-12664a1c-0000", true);  //张三同意张三三三
    // process_apply_test("f7aa-b126b9c7-0001", "41d1-b0335c8f-0000", false);  //张三拒绝李四
    // process_apply_test("f7aa-b126b9c7-0001", "1460-080c2225-0001", true);    //张三同意王五

    // search_test("f7aa-b126b9c7-0001", "李四"); //有
    // search_test("f7aa-b126b9c7-0001", "张三三三");  //没有
    // search_test("21df-12664a1c-0000", "王五");  //有2个
    // friend_list_test("f7aa-b126b9c7-0001"); //2
    // friend_list_test("41d1-b0335c8f-0000"); //0
    
    // friend_remove_test("f7aa-b126b9c7-0001", "1460-080c2225-0001"); //删除好友
    // friend_list_test("f7aa-b126b9c7-0001"); 

    //friend_remove_test("f7aa-b126b9c7-0001", "1460-080c2225-0001"); //删除好友
    //friend_list_test("f7aa-b126b9c7-0001"); 

    //张三三三把张三 李四 王五 王五五 赵六 拉进群聊
    //create_groupcss_test("21df-12664a1c-0000", {"21df-12664a1c-0000", "f7aa-b126b9c7-0001", "41d1-b0335c8f-0000", "1460-080c2225-0001", "b4ce-6ceee502-0003", "9dbd-b84377c2-0002"});
    //css_member_test("21df-12664a1c-0000", "b287-4a734db1-0000");
    css_list_test("21df-12664a1c-0000");

    return 0;
}